package com.hpe.service.Impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hpe.dao.ClassHistoryMapper;
import com.hpe.dao.ClassNumMapper;
import com.hpe.dao.SClassMapper;
import com.hpe.dao.StudentInfoMapper;
import com.hpe.pojo.ClassHistory;
import com.hpe.pojo.ClassNum;
import com.hpe.pojo.SClass;
import com.hpe.pojo.StudentInfo;
import com.hpe.service.StudentInfoService;
import com.hpe.service.StudentService;
import com.hpe.util.DownloadUtil;
import com.hpe.util.ExcelUtil;
import com.hpe.util.ServerResponse;
import com.hpe.vo.StudentInfoVo;
import com.hpe.vo.StudentVo;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by chunjie on 2017/9/23.
 */
@Service
public class StudentInfoServiceImpl implements StudentInfoService {

    @Autowired
    private StudentInfoMapper studentInfoMapper;

    @Autowired
    private StudentService studentService;

    @Autowired
    private ClassHistoryMapper classHistoryMapper;

    @Autowired
    private ClassNumMapper classNumMapper;

    @Autowired
    private SClassMapper sClassMapper;

    private Logger logger = LoggerFactory.getLogger(StudentInfoService.class);

    @Override
    @Transactional
    public ServerResponse<StudentInfo> updateByPrimaryKeySelective(StudentInfo record) {
        //根据方向关联 查询班级
        SClass sClass = sClassMapper.selectDirectionClass(Integer.parseInt(record.getDirection()));

        if (sClass != null) {

            StudentInfo studentInfo = studentInfoMapper.selectByPrimaryKey(record.getId());
            //只有第一次完善信息时变更历史
            if ("0".equals(studentInfo.getSpare())) {
                //插入班级历史
                classHistoryMapper.insert(new ClassHistory(0, studentInfo.getId(), sClass.getId(), studentInfo.getName(), "0", new java.util.Date()));
                //班级人数统一
                ClassNum oldClassNum = classNumMapper.selectLastClassNumById(0);
                ClassNum newClassNum = classNumMapper.selectLastClassNumById(sClass.getId());
                //获取原班级人数并且更新（减一操作）
                classNumMapper.insertSelective(new ClassNum(0, 0, oldClassNum.getcNum() - 1, new Date(), null));
                //更新当前新班级人数（加一操作）
                classNumMapper.insertSelective(new ClassNum(0, sClass.getId(), newClassNum.getcNum() + 1, new Date(), null));
            }
        }

        if (sClass != null) {
            record.setSpare(sClass.getId() + "");
        }

        //更新
        int result = studentInfoMapper.updateByPrimaryKeySelective(record);
        if (result <= 0) {
            return ServerResponse.createByErrorMsg("信息更新失败");
        }


        return ServerResponse.createBySuccess("更新成功", selectByKey(record.getId()));

    }

    @Override
    public StudentInfo selectByKey(Integer id) {
        return studentInfoMapper.selectByPrimaryKey(id);
    }

    @Override
    public String findNameByPrimaryKey(Integer id) {
        String name = studentInfoMapper.findNameByPrimaryKey(id);
        return name;
    }

    @Override
    public ServerResponse<PageInfo> getStudentList(int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<StudentVo> studentInfos = studentInfoMapper.getStudentList();
        PageInfo pageInfo = new PageInfo(studentInfos);
        return ServerResponse.createBySuccess(pageInfo);
    }

    @Override
    public ServerResponse<PageInfo> getNotOnlineStudentList(int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<StudentVo> studentInfos = studentInfoMapper.getNotOnlineStudentList();
        PageInfo pageInfo = new PageInfo(studentInfos);
        return ServerResponse.createBySuccess(pageInfo);
    }

    @Override
    public ServerResponse<String> updateStudentInfoSpare(int id, int spare) {
        int count = studentInfoMapper.updateStudentSpare(id, spare);
        if (count > 0) {
            return ServerResponse.createBySuccessMsg("更新班级成功");
        }
        return ServerResponse.createByErrorMsg("更新班级失败");
    }

    @Override
    public ServerResponse<String> updateStudentInfoDirection(int id, int direction) {
        int count = studentInfoMapper.updateStudentDirection(id, direction);
        if (count > 0) {
            return ServerResponse.createBySuccessMsg("更新方向成功");
        }
        return ServerResponse.createByErrorMsg("更新方向失败");
    }

    @Override
    public ServerResponse<String> updateStudentInfoState(int id, int state) {
        int count = studentInfoMapper.updateStudentState(id, state);
        if (count > 0) {
            return ServerResponse.createBySuccessMsg("更新状态成功");
        }
        return ServerResponse.createByErrorMsg("更新状态失败");
    }

    @Override
    public ServerResponse<String> updateStudentInfoNewId(int id, int newId) {
        int count = studentInfoMapper.updateStudentNewId(id, newId);
        if (count > 0) {
            return ServerResponse.createBySuccessMsg("更新学号成功");
        }
        return ServerResponse.createByErrorMsg("更新学号失败");
    }

    @Override
    public ServerResponse<StudentInfoVo> getDetailById(int id) {
        StudentInfoVo info = studentInfoMapper.findStudentByPrimaryKey(id);
        if (info == null) {
            return ServerResponse.createByErrorMsg("查询不到内容，请确认后重新查询");
        }
        return ServerResponse.createBySuccess(info);
    }

    @Override
    public ServerResponse<StudentInfo> getStudentPartInfo(int id) {
        StudentInfo info = studentInfoMapper.getStudentPartInfo(id);
        if (info == null) {
            return ServerResponse.createByErrorMsg("查询不到内容，请确认后重新查询");
        }
        return ServerResponse.createBySuccess(info);
    }


    @Override
    public ServerResponse<PageInfo> getStudentInfoByCondition(int pageNum, int pageSize, String school, int direction, String spare, String name) {
        PageHelper.startPage(pageNum, pageSize);
        List<StudentVo> studentInfos = studentInfoMapper.getStudentsByCondition(name, school, spare, direction);
        PageInfo pageInfo = new PageInfo(studentInfos);
        return ServerResponse.createBySuccess(pageInfo);
    }

    @Override
    public String findClassByPrimaryKey(Integer id) {
        return studentInfoMapper.findClassByPrimaryKey(id);
    }

    @Override
    public ServerResponse<String> graduationStudent() {
        int onlineCount = studentInfoMapper.getOnSchoolStudentCount();
        if (onlineCount < 1) {
            return ServerResponse.createByErrorMsg("当前所有学生都已离校");
        }
        int count = studentInfoMapper.graduationStudent();
        if (count > 0) {
            return ServerResponse.createBySuccessMsg("更新操作成功");
        }
        return ServerResponse.createByErrorMsg("更新操作失败，请重新再试");
    }

    @Override
    public ServerResponse<String> updateStudentPartInfomation(int id, int state, int newId, int direction, String spare) {
        //班级有更新则存入班级历史表
        StudentInfo studentInfo = studentInfoMapper.selectByPrimaryKey(id);
        if (null != studentInfo.getSpare() && !studentInfo.getSpare().equals(spare)) {
            if (!studentInfo.getSpare().equals(spare)) {
                //班级历史表插入
                ClassHistory classHistory = new ClassHistory();
                //设置学生信息
                classHistory.setsId(studentInfo.getId());
                classHistory.setsName(studentInfo.getName());
                //设置创建时间
                classHistory.setHistoryTime(new Date());
                //设置当前班级id
                classHistory.setClassId(Integer.parseInt(spare));
                //设置历史班级id
                classHistory.setSpare(studentInfo.getSpare());
                //执行插入
                int resultRow = classHistoryMapper.insert(classHistory);
                if (resultRow <= 0) {
                    return ServerResponse.createByErrorMsg("信息更新失败");
                }

                //班级人数表更新（新班级）
                ClassNum newClassNumUpdate = new ClassNum();
                ClassNum classNumCurrent = classNumMapper.selectLastClassNumById(Integer.parseInt(spare));
                newClassNumUpdate.setcId(Integer.parseInt(spare));
                //设置更新时间
                newClassNumUpdate.setChangeDate(new Date());
                //更新班级人数
                newClassNumUpdate.setcNum(classNumCurrent.getcNum() + 1);
                resultRow = classNumMapper.insert(newClassNumUpdate);
                if (resultRow <= 0) {
                    return ServerResponse.createByErrorMsg("信息更新失败");
                }

                //班级人数表更新（旧班级）
                ClassNum oldClassNumUpdate = new ClassNum();
                ClassNum oldClassNumCurrent = classNumMapper.selectLastClassNumById(Integer.parseInt(studentInfo.getSpare()));
                oldClassNumUpdate.setcId(Integer.parseInt(studentInfo.getSpare()));
                //设置更新时间
                oldClassNumUpdate.setChangeDate(new Date());
                //更新班级人数
                oldClassNumUpdate.setcNum(oldClassNumCurrent.getcNum() - 1);
                resultRow = classNumMapper.insert(oldClassNumUpdate);
                if (resultRow <= 0) {
                    return ServerResponse.createByErrorMsg("信息更新失败");
                }
            }
        }

        if (id <= 0) {
            return ServerResponse.createByErrorMsg("参数错误，请重新操作");
        }

        int count = studentInfoMapper.updateStudentPartInfomation(id, state, newId, direction, spare);
        if (count > 0) {
            return ServerResponse.createBySuccessMsg("更新学生信息成功");
        }
        return ServerResponse.createByErrorMsg("更新学生信息失败");
    }

    /**
     * @return true 存在 / false 不存在
     * @description 删除方向时检索是否具有该方向的学生
     * @author Fujt
     * @date 2017/10/20 11:09
     */
    @Override
    public boolean findByDirectionExistOrNot(int direction) {
        return (studentInfoMapper.findByDirectionExistOrNot(direction) != null);
    }

    @Override
    public void outputStudentRegisterExcelTitle(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String[] title = {"姓名", "性别", "电话", "民族", "身份证号", "学校", "学院", "专业", "班级", "学号", "学生志愿"};
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet("sheet1");
        XSSFRow row = sheet.createRow(0);

        Font font = workbook.createFont();
        font.setBold(true);
        font.setFontName("楷体");
        font.setFontHeightInPoints((short) 13);

        XSSFCellStyle style = workbook.createCellStyle();
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setFont(font);

        for (int i = 0; i < title.length; i++) {
            XSSFCell cell = row.createCell(i);
            cell.setCellStyle(style);
            cell.setCellValue(title[i]);
            cell.setCellType(CellType.STRING);
        }

        for (int i = 0; i < title.length; i++) {
            sheet.setColumnWidth(i, title[i].getBytes().length * 2 * 256);
        }

        XSSFCell cellEx = row.createCell(title.length);
        String comment = "注意，请在纯数字前加入英文单引号['],此列不要输入内容";
        cellEx.setCellValue(comment);
        cellEx.setCellStyle(style);
        sheet.setColumnWidth(title.length, comment.getBytes().length * 2 * 180);


        ByteArrayOutputStream os = new ByteArrayOutputStream();
        workbook.write(os);
        workbook.close();
        new DownloadUtil().download(os, resp, req, "学生登记表.xlsx");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServerResponse<String> registerStudentFromExcel(InputStream is) throws Exception {
        ExcelUtil excelUtil = new ExcelUtil(is, "2007");
        String[] beanProperties = {"Name", "Sex", "Tel", "Nation", "Number", "School", "College", "Major", "SchoolClass", "SchoolId", "StuOrder"};
        Class<?>[] propertyTypes = {String.class, String.class, String.class, String.class, String.class, String.class, String.class, String.class, String.class, String.class, String.class};
        List<StudentInfo> studentInfoList = new ArrayList<StudentInfo>();
        try {
            studentInfoList = excelUtil.readExcel(beanProperties, propertyTypes, StudentInfo.class);
        } catch (Exception e) {
            logger.error(e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ServerResponse.createByErrorMsg("文件解析出错，请确认每个单元格都为文本格式,且数据信息和导出表头信息相对应");
        }
        if (studentInfoList.size() == 0) {
            return ServerResponse.createByErrorMsg("请上传一个有有效数据的文件");
        }
        try {
            for (int i = 0, length = studentInfoList.size(); i < length; i++) {
                ServerResponse response = studentService.register(studentInfoList.get(i), "7C4A8D09CA3762AF61E59520943DC26494F8941B");
                if (!response.isSuccess()) {
                    logger.error(response.getMsg());
                    throw new Exception("第" + (i + 1) + "行学生数据出错," + response.getMsg() + "，请重试");
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ServerResponse.createByErrorMsg(e.getMessage());
        }
        return ServerResponse.createBySuccessMsg("导入学生数据成功");
    }


}
